In this notebook we classify all symmetry-exceptional slopes of the asymmetric L-space knots in the SnapPy census. For that we compute (as explained in the paper) for any knot the slopes with length less than 10.2 and compute the symmetry groups of the corresponding fillings.
We start with the 9 asymmetric L-space knots.
D=['t12533','t12681','o9_38928','o9_39162','o9_40363','o9_40487','o9_40504','o9_40582','o9_42675']
The corresponding code is as follows.
import math
import pandas
import time
import snappy
# We load Dunfield's list from of all exceptional surgeries along the SnapPy CensusKnots.
exceptional_filllings = pandas.read_csv("exceptional_fillings.csv")
def better_symmetry_group(M,index=10,time_cut_off=False,max_time=60):
'''
This function computes the verified symmetry group of the input manifold.
If SnapPy cannot rigorously the symmetry group it returns 'unclear'.
The higher the index the harder SnapPy searches. A time limit is possible.
'''
start_time = time.time()
w=False
randomizeCount=0
try:
S=M.symmetry_group()
w=S.is_full_group()
except ValueError:
pass
except RuntimeError:
pass
except snappy.SnapPeaFatalError:
pass
if w==False:
while randomizeCount<index and w==False:
M.randomize()
randomizeCount=randomizeCount+1
try:
S=M.symmetry_group()
w=S.is_full_group()
except ValueError:
pass
except RuntimeError:
pass
except snappy.SnapPeaFatalError:
pass
if time_cut_off==True and (time.time() - start_time) >max_time:
return 'unclear'
if w==True:
return S
if w==False:
return 'unclear'
def Bound(systole):
'''
Takes as input a systole and computes the bound from FPS19.
'''
B= math.sqrt(2*math.pi/systole +58)
if 10.1>B:
return 10.11
else:
return B+0.01
def better_systole(M,index):
'''
Computes the systole of a manifold.
It returns 'unclear' if SnapPy cannot compute the systole.
'''
w=False
randomizeCount=0
try:
systole=M.dual_curves()[0].complete_length.real()
w=True
except ValueError:
pass
except RuntimeError:
pass
except SnapPeaFatalError:
pass
except IndexError:
pass
if w==False:
while randomizeCount<index and w==False:
M.randomize()
randomizeCount=randomizeCount+1
try:
systole=M.length_spectrum()[0].length.real()
w=True
except ValueError:
pass
except RuntimeError:
pass
except snappy.SnapPeaFatalError:
pass
except IndexError:
pass
if w==True:
return systole
if w==False:
return 'unclear'
def exceptional_slopes(knot):
"""
Takes a knot from the SnapPy census and reads off from Dunfield's list its exceptional surgeries.
"""
exceptional_slopes_strings=exceptional_filllings.loc[(exceptional_filllings['cusped'] == knot)]['slope'].tolist()
exceptional_slopes=[]
for string in exceptional_slopes_strings:
string_without_brackets=string[1:-1]
exceptional_slopes.append(tuple(map(int, string_without_brackets.split(', '))))
return exceptional_slopes
def compute_exceptional_symmetry_slopes(knot,index=10,time_cut=False,max_time_cut_off=120):
'''
Returns the exceptional symmetry slopes, the exceptional slopes and and the slopes where SnapPy could not compute its symmetry groups.
'''
start_time = time.time()
K=snappy.Manifold(knot)
systole=better_systole(K,index)
if systole=='unclear':
return [K.name(),'cannot compute systole']
B=Bound(systole)
exc_slopes=exceptional_slopes(knot)
small_slopes=[s for s in K.short_slopes(length=B*math.sqrt(K.cusp_areas()[0]))[0] if s not in exc_slopes] # The small hyperbolic slopes.
exceptional_symmetry_slopes=[]
smaller_groups=[]
unclear_slopes=[]
S=better_symmetry_group(K,index)
if S=='unclear':
return [K.name(),'cannot compute symmetry group']
for s in small_slopes:
K.dehn_fill(s)
if time_cut==True and (time.time() - start_time) >max_time_cut_off:
unclear_slopes.append(s)
else:
T=better_symmetry_group(K,index,time_cut_off=time_cut,max_time=max_time_cut_off/10)
if T=='unclear':
unclear_slopes.append(s)
else:
if T.order()>S.order():
exceptional_symmetry_slopes.append([s,T])
if T.order()<S.order():
smaller_groups.append([s,T])
return [K.name(),S,len(small_slopes),exc_slopes,exceptional_symmetry_slopes,smaller_groups,unclear_slopes]
EXSYM=[]
start_time = time.time()
for K in D:
EXSYM.append(compute_exceptional_symmetry_slopes(K,index=1000))
print("--- Time taken: %s minutes ---" % ((time.time() - start_time)/60))
--- Time taken: 5.907751727104187 minutes ---
We get the list of exceptional symmetry slopes as claimed in the paper.
EXSYM
[['t12533', 0, 97, [(1, 0)], [[(-3, 1), Z/2], [(-2, 1), Z/2], [(-1, 1), Z/2], [(0, 1), Z/2], [(1, 1), Z/2], [(-1, 2), Z/2]], [], []], ['t12681', 0, 96, [(1, 0), (0, 1)], [[(-1, 1), Z/2], [(1, 1), Z/2 + Z/2], [(-1, 2), Z/2], [(-2, 3), Z/2], [(-1, 3), Z/2]], [], []], ['o9_38928', 0, 100, [(1, 0)], [[(-2, 1), Z/2], [(-1, 1), Z/2], [(0, 1), Z/2], [(1, 1), Z/2], [(2, 1), Z/2 + Z/2]], [], []], ['o9_39162', 0, 95, [(1, 0), (0, 1)], [[(-1, 1), Z/2], [(1, 1), Z/2], [(2, 1), Z/2], [(1, 2), Z/2], [(1, 4), Z/2]], [], []], ['o9_40363', 0, 98, [(1, 0), (0, 1)], [[(-1, 1), Z/2], [(1, 1), Z/2 + Z/2], [(-1, 2), Z/2], [(-1, 3), Z/2], [(-3, 4), Z/2]], [], []], ['o9_40487', 0, 100, [(1, 0)], [[(-2, 1), Z/2], [(-1, 1), Z/2], [(0, 1), Z/2], [(1, 1), Z/2], [(2, 1), Z/2], [(3, 1), Z/2], [(1, 2), Z/2]], [], []], ['o9_40504', 0, 99, [(1, 0)], [[(-2, 1), Z/2], [(-1, 1), Z/2], [(0, 1), Z/2], [(1, 1), Z/2], [(2, 1), Z/2 + Z/2]], [], []], ['o9_40582', 0, 97, [(1, 0)], [[(-1, 1), Z/2], [(0, 1), Z/2], [(1, 1), Z/2], [(2, 1), Z/2], [(4, 1), Z/2], [(1, 2), Z/2]], [], []], ['o9_42675', 0, 99, [(1, 0)], [[(-2, 1), Z/2 + Z/2], [(-1, 1), Z/2], [(0, 1), Z/2], [(1, 1), Z/2], [(2, 1), Z/2]], [], []]]
Since for any knot the last two sets are empty it follows that our results are complete and that we have actually found any symmetric slope of the knots in D.